//
//  Application.swift
//  UICore
//
//  Created by Flutter on 2021/7/6.
//

import UIKit
 import Standard

public enum Application {}

private extension Application {
    static let lock = ReadWriteLock()
    static var observers = [AnyApplicationObservable]()
}

private extension Application {
    static func flatten() {
        lock.withWriterLockVoid { observers = observers.filter { !$0.isRemovable } }
    }
}

public extension Application {
    static func add(observable: ApplicationObservable) {
        lock.withWriterLockVoid { observers.append(AnyApplicationObservable(observable: observable)) }
    }
}

public extension Application {
    static func scene(_ scene: UIWindowScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) -> UIWindow? {
        return nil
    }
}

public extension Application {
    
    static func sceneDidDisconnect(_ scene: UIScene) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.sceneDidDisconnect() } }
    }

    static func sceneDidBecomeActive(_ scene: UIScene) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.sceneDidBecomeActive() } }
    }

    static func sceneWillResignActive(_ scene: UIScene) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.sceneWillResignActive() } }
    }

    static func sceneWillEnterForeground(_ scene: UIScene) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.sceneWillEnterForeground() } }
    }

    static func sceneDidEnterBackground(_ scene: UIScene) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.sceneDidEnterBackground()} }
    }
    
}

public extension Application {
    
    static func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.scene(continue: userActivity) } }
    }
    
    static func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        flatten()
        lock.withReaderLockVoid { observers.forEach { $0.observable?.scene(openURLContexts: URLContexts)} }
        
//        guard let URLContext = URLContexts.first  else { return }
//        print(URLContext.url)
    }
    
    static func canOpen(url: URL) -> Bool {
        return UIApplication.shared.canOpenURL(url)
    }
    
}

